package org.tis.tools.starter.mybatisplus.querykit.model;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.tis.tools.model.exception.ToolsRuntimeException;
import org.tis.tools.starter.mybatisplus.querykit.enums.QueryLogic;

import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.List;

/**
 * description: 查询对象
 *
 * @author zhaoch
 * @date 2018/10/8
 **/
@Data
@Slf4j
public class Query<T> implements Serializable {

    /**
     * 分页信息
     */
    @NotNull(message = "分页对象不能为空")
    private QueryPage page;

    /**
     * 查询条件
     */
    private List<QueryUnit> condition;

    /**
     * 获取查询的wrapper类
     * @return
     */
    public Wrapper<T> getWrapper() {
        EntityWrapper<T> wrapper = new EntityWrapper<>();
        if (CollectionUtils.isEmpty(condition)) {
            return null;
        }
        for (int i = 0; i < condition.size(); i++) {
            if (i != 0) {
                if (condition.get(i).getLogic().equals(QueryLogic.OR)) {
                    wrapper.orNew();
                } else {
                    wrapper.andNew();
                }
            }
            for (BaseQuery query : condition.get(i).getQueryList()) {
                if (query.getLogic().equals(QueryLogic.OR)) {
                    wrapper.or();
                }
                //根据类名获取Class对象
                //参数类型数组
                Class[] parameterTypes={QueryLogic.class, List.class};
                try {
                    //根据参数类型获取相应的构造函数
                    Constructor constructor = query.getOperator().getClazz().getConstructor(parameterTypes);
                    //参数数组
                    Object[] parameters = {query.getLogic(), query.getParams()};
                    //根据获取的构造函数和参数，创建实例
                    IQuery<T> q = (IQuery<T>)constructor.newInstance(parameters);
                    q.handleWrapper(wrapper);
                } catch (Exception e) {
                    log.error("实例化查询条件错误", e);
                    throw new ToolsRuntimeException("CTL-500", "IQuery实现类出现错误!");
                }
            }
        }
        return wrapper;
    }

    /**
     * 获取分页对象，区别于QueryPage，该查询对象用于mp的查询分页
     * @return
     */
    public Page<T> getPageObj() {
        com.baomidou.mybatisplus.plugins.Page<T> p = new com.baomidou.mybatisplus.plugins.Page<>(page.getCurrent(), page.getSize());
        if (page.getOrderByField() != null) {
            p.setOrderByField(page.getOrderByField());
            p.setAsc(page.getAsc());
        }
        return p;
    }

}

